package com.yeeKa.common.exception;

//import com.alibaba.nacos.api.exception.NacosException;
import com.google.common.collect.ImmutableMap;
import com.yeeKa.common.response.ResponseResult;
import com.yeeKa.enums.StatusCode;
import org.mybatis.spring.MyBatisSystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;

/**
 * 拦截 BusinessException 自定义异常
 *
 * @author win10
 */
@RestControllerAdvice
public class ExceptionAdvice {

    private static final Logger log = LoggerFactory.getLogger(ExceptionAdvice.class);

    @ExceptionHandler(BusinessException.class)
    public ResponseResult<?> catchBusinessException(BusinessException e) {
        log.error(e.getMsg(), e);
        return ResponseResult.errorResult(e.getCode(), e.getMsg());
    }

    @ExceptionHandler(IOException.class)
    public ResponseResult<?> catchBusinessException(IOException e) {
        log.error(" IO异常：", e);
        return ResponseResult.errorResult(StatusCode.IO_ERROR.getCode(), StatusCode.IO_ERROR.getMessage());
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ResponseResult<?> catchMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        log.error(" 缺少必要参数："+e.getParameterName(), e);
        return ResponseResult.errorResult(StatusCode.PARAM_REQUIRE.getCode(), StatusCode.PARAM_REQUIRE.getMessage()+e.getParameterName());
    }

//    @ExceptionHandler(NacosException.class)
//    public ResponseResult<?> catchBusinessException(NacosException e) {
//        log.error("Nacos config 配置 异常:", e);
//        return ResponseResult.errorResult(StatusCode.ERROR.getCode(), "Nacos config 配置 异常");
//    }

    @ExceptionHandler(Exception.class)
    public ResponseResult<?> catchException(Exception e) {
        // 捕获异常类
        Class<? extends Exception> exClass = e.getClass();
        if (EXCEPTIONS == null) {
            EXCEPTIONS = builder.build();
        }
        // 先到 Map 里面找 异常 有 直接返回
        ResponseResult<?> responseResult = EXCEPTIONS.get(exClass);
        if (responseResult == null) {
            log.error(" 未知异常：", e);
            return ResponseResult.errorResult(StatusCode.ERROR.getCode(), e.toString());
        }
        log.error(" 已分类异常："+responseResult.getMessage(), e);
        return responseResult;
    }

    /**
     * ImmutableMap一旦创建不可改变，并且线程安全
     */
    private static ImmutableMap<Class<? extends Throwable>, ResponseResult<?>> EXCEPTIONS;

    /**
     * 构建异常类型和错误代码的对象
     */
    protected static ImmutableMap.Builder<Class<? extends Throwable>, ResponseResult<?>> builder = ImmutableMap.builder();

    static {
        // 新增异常类
        builder.put(ArithmeticException.class, ResponseResult.errorResult(StatusCode.ARITHMETIC_ERROR));
        builder.put(NullPointerException.class, ResponseResult.errorResult(StatusCode.NullPointer_ERROR));
        builder.put(BadSqlGrammarException.class, ResponseResult.errorResult(StatusCode.SQL_ERROR));
        builder.put(DataIntegrityViolationException.class, ResponseResult.errorResult(StatusCode.SQL_ERROR));
        builder.put(UncategorizedSQLException.class, ResponseResult.errorResult(StatusCode.SQL_ERROR));
        builder.put(MyBatisSystemException.class, ResponseResult.errorResult(StatusCode.SQL_ERROR));
    }
}